<template>
  <!-- 地图容器 -->
  <div class="ol-map" id="olMap" :style="styles">
    <slot></slot>
  </div>
</template>

<script>
import {
  defineComponent,
  watch,
  getCurrentInstance,
  nextTick,
  provide,
  onMounted,
  onUnmounted,
} from 'vue';
import { $once, $emit } from 'vue-happy-bus';
import { bMapTileConfig } from './config/baiduConfig';
import NanMingMapConfig from './config/nanming.config.json';
import { wjPgisTileConfig } from './config/wujiangPgisConfig';
// import { shandongPgisConfig } from './config/shandongConfig';
// import { haidianBaiduMapConfig } from './config/haidianConfig';
// import { ahLayer, ahView } from './config/ah-hf-config'; // ahMapConfig
import baiduLayer from './config/baiduLayer';
// import { arrAverageNum } from '@/service/UtilService';
/**
 * 根据数组求平均值
 * @param {Array} arr 数组
 * @returns {Number} 平均值
 */
export const arrAverageNum = arr => {
  if (!arr.every(o => toString.call(o) === '[object Number]')) {
    return NaN;
  }
  let sum = eval(arr.join('+'));
  return ~~((sum / arr.length) * 100) / 100;
};
// import { queryAreaList } from '@/service/modulesApi/map.js';
// import './js/mapping/index.css';

let markerFeatures = [];
let sourceVector = null;
let markerVectorLayer = null;

// 导入ol
import Map from 'ol/map';
import View from 'ol/view';
import Source from 'ol/source/source';
import SourceVector from 'ol/source/vector';
import XYZ from 'ol/source/xyz';
import OSM from 'ol/source/osm';
import Cluster from 'ol/source/cluster';
import TileImage from 'ol/source/tileimage';
import WMTS from 'ol/source/wmts';

import Tilegrid from 'ol/tilegrid';
import TileGrid from 'ol/tilegrid/tilegrid';
import Layer from 'ol/layer/layer';
import layerTile from 'ol/layer/tile';
import LayerGroup from 'ol/layer/group';

import layerVector from 'ol/layer/vector';

import Control from 'ol/control';
import olProj from 'ol/proj';
import olInteraction from 'ol/interaction';
import geomPoint from 'ol/geom/point';
import geomPolygon from 'ol/geom/polygon';
import Heatmap from 'ol/layer/heatmap';
import GeoJSON from 'ol/format/geojson';
import Observable from 'ol/observable';
import Feature from 'ol/feature';
import Overlay from 'ol/overlay';

import Style from 'ol/style/style';
import Text from 'ol/style/text';
import Fill from 'ol/style/fill';
import Icon from 'ol/style/icon';
import Stroke from 'ol/style/stroke';
import Circle from 'ol/style/circle';
import ScaleLine from 'ol/control/scaleline';
import { createLayer } from './utils/layer';
// 自定义坐标转化
function toCoordinate(str) {
  var _str = String(str).replace(/(\d+\.\d+),(\d+\.\d+),/g, '$1,$2;');
  let coordinates = _str.split(';');
  coordinates.forEach((item, index) => {
    coordinates[index] = item.split(',');
  });
  return coordinates;
}

export default defineComponent({
  name: 'olMap',
  props: {
    // 图层适配器, {id,type, url, layers(天地图专用)}
    adapter: {
      type: [String, Object, Function],
      default: 'Baidu',
    },
    // 指定经纬度字段值为对象的某个属性值
    props: {
      type: Object,
      default: () => {
        return {
          longitude: 'longitude',
          latitude: 'latitude',
        };
      },
    },
    width: {
      type: String,
      default: '100%',
    },
    height: {
      type: String,
      default: '350px',
    },
  },
  emits: ['ready'],
  setup(props) {
    const { proxy } = getCurrentInstance(); // 获取当前组件实例
    provide('myMap', proxy);
    /**
     * 地图初始化完成回调
     * @method mapReady
     * @param callback
     */
    const mapReady = callback => {
      //   console.log('模块=map】 【mapReady】', proxy.mapInstance);
      if (proxy.mapInstance) {
        callback && callback(proxy.mapInstance, proxy);
        return;
      }
      $once('ready', callback);
    };

    /**
     * 移动到指定经纬度居中
     * @method moveTo
     * @param {Number[]} loc 经纬度数组
     */
    const moveTo = loc => {
      if (!proxy.mapInstance) return;
      const view = proxy.mapInstance.getView();
      view.animate({
        center: loc,
        duration: 200,
      });
    };

    onMounted(() => {
      proxy.mapInit(); // 地图初始化
      proxy.addMouseEvent(); // 添加地图事件
      // proxy.getBorderData(); // 渲染边界数据
    });
    onUnmounted(() => {
      proxy.removeVectorLayerBorder();
      proxy.clearMapObject();
      proxy.removeEvent(proxy.moveendEventHandle);
      proxy.removeEvent(proxy.movestartEventHandle);
      proxy.removeEvent(proxy.pointermoveEventHandle);
      proxy.mapInstance = null;
    });

    return {
      mapReady,
      moveTo,
    };
  },
  data() {
    return {
      isShow: false,
      mapInstance: null, //地图实例
      dataList: [], //数据
      poiLayer: null, //poi图层
      heatMapLayer: null, //热力图层
      clusterSource: null, //类聚数据源
      clustersLayer: null, //类聚图层
      keyAreasOverlays: [], //辖区分布图层
      vectorLayerBorders: [], //区域边界图层
      windowOverlay: null, //弹框图层
      poiOverlays: [], //
      highlightMarker: '', //当前高亮的marker
      moveendEventHandle: null,
      movestartEventHandle: null,
      pointermoveEventHandle: null,
    };
  },
  computed: {
    styles() {
      return {
        width: this.width,
        height: this.height,
      };
    },
  },
  methods: {
    // 获取辖区边界数据
    // getBorderData() {
    //   queryAreaList({})
    //     .then(res => {
    //       this.createAreaBorder(res.RESULT);
    //       // 监听鼠标移动事件 添加边界交互
    //       this.pointermoveEventHandle = this.mapInstance.on('pointermove', e => {
    //         let pixel = this.mapInstance.getEventPixel(e.originalEvent);
    //         try {
    //           var hit = this.mapInstance.hasFeatureAtPixel(pixel);
    //           let index = 0;
    //           if (hit) {
    //             //获取到当前像素下的图层layer
    //             // let layer = this.mapInstance.forEachLayerAtPixel(pixel, layer =>layer);
    //             //获取到当前像素下的feature
    //             let feature = this.mapInstance.forEachFeatureAtPixel(pixel, feature => feature);
    //             index = feature.get('id');
    //             index && this.keyAreasOverlayMouseenter({ area: 1 }, index);
    //           } else {
    //             this.keyAreasOverlayMouseleave({ area: 1 }, index);
    //           }
    //         } catch (err) {
    //           console.log('pointermove err', err);
    //         }
    //       });
    //     })
    //     .catch(err => {
    //       console.log(err);
    //     });
    // },
    // 初始化地图
    mapInit() {
      const MAP = {
        osmMapInit: 'osmMapInit', // 世界-osm地图
        baiduInternet: 'baiduMapInit', // 外网百度-地图
        sdPgisMap: 'sdPgisMapInit', // 山东省厅-pgis地图
        sdTianMap: 'sdTianMapInit', // 山东省厅-天地图
        haidianMap: 'haidianMapInit', // 北京海淀-百度地图
        gaoDeInternetMap: 'gaoDeInternetInitMap', //高德外网地图
        gaoLANDeMap: 'gaoLANDeInitMap', //上海高德内网地图
        wjPgisMap: 'wjPgisMapInit', // 吴江pgis-地图
        wjSfMap: 'wjSfInitMap', // 吴江-顺丰地图
        ahSuperMap: 'ahSuperMapInit', // 安徽省厅-超图
        NanMingMap: 'NanMingMapInit', // 贵阳南明-北大方正地图
      };
      // 容错处理(window.g.mapTyp 为空时，默认为 'baiduMapInit')
      let handle = MAP[window.g.mapType] || 'baiduMapInit';
      this[handle]();

      /**
       * 地图初始化完成时触发
       * @event ready
       * @param {Map} map ol/Map实例
       * @param {VueComponent} vm Vue实例
       */
      $emit('ready', this.mapInstance, this);
      this.$emit('ready', this.mapInstance, this);
    },
    osmMapInit() {
      this.mapView = new View({
        center: [0, 0],
        zoom: 2,
      });
      this.mapInstance = new Map({
        layers: [
          new layerTile({
            source: new OSM(),
          }),
        ],
        target: 'olMap',
        view: this.mapView,
      });
    },
    // 吴江pgis地图
    wjPgisMapInit() {
      let tilegrid = new TileGrid({
        origin: wjPgisTileConfig.tileGrid.origin, // 设置原点坐标
        resolutions: wjPgisTileConfig.tileGrid.resolutions, // 设置分辨率
      });

      // 创建地图的数据源
      let mapSource = new TileImage({
        projection: wjPgisTileConfig.projection,
        tileGrid: tilegrid,
        tileUrlFunction: wjPgisTileConfig.tileUrlFunction,
      });

      // 地图图层
      let mapLayer = new layerTile({
        source: mapSource,
      });
      this.mapView = new View({
        center: window.g.center,
        projection: 'EPSG:4326',
        zoom: window.g.defaultZoom,
        minZoom: window.g.minZoom,
        maxZoom: window.g.maxZoom,
      });
      this.mapView.set('maxZoom', window.g.maxZoom);

      // 创建地图
      this.mapInstance = new Map({
        layers: [mapLayer],
        view: this.mapView,
        target: 'olMap',
      });
    },
    // 外网百度地图
    baiduMapInit() {
      const layer = createLayer('Baidu');
      this.mapView = new View({
        center: [113.261999, 23.130592],
        projection: 'EPSG:4326',
        zoom: bMapTileConfig.defaultZoom,
        minZoom: bMapTileConfig.minZoom,
        maxZoom: bMapTileConfig.maxZoom,
      });
      this.mapView.set('maxZoom', bMapTileConfig.maxZoom);
      this.mapInstance = new Map({
        layers: [].concat(layer),
        view: this.mapView,
        target: 'olMap',
      });
    },
    // 山东省厅pgis地图
    // sdPgisMapInit() {
    //   let projection = olProj.get(shandongPgisConfig.projection);
    //   let tileGrid = new Tilegrid.WMTS({
    //     origin: shandongPgisConfig.tileGrid.origin, // 设置原点坐标
    //     resolutions: shandongPgisConfig.tileGrid.resolutions, // 设置分辨率
    //     matrixIds: shandongPgisConfig.tileGrid.matrixIds,
    //     // extent:[ -180,-90,180,90 ], //[112.52197,34.05761,123.53027,39.39697]   [-180,-90,180,90]
    //     tileSize: [256, 256],
    //   });
    //   let layer = new layerTile({
    //     opacity: 0.7,
    //     source: new WMTS({
    //       url: 'http://10.48.105.45:8080/EzServer/Maps/sl2018',
    //       layer: 'layer0',
    //       style: 'default',
    //       matrixSet: 'layer0', //投影坐标系设置矩阵 EPSG:4326 3857 layer0
    //       format: 'tiles', //"image/png"  tiles 图片格式
    //       wrapX: true,
    //       version: '1.0.0',
    //       tileGrid: tileGrid,
    //     }),
    //   });

    //   this.mapView = new View({
    //     center: [shandongPgisConfig.defaultJd, shandongPgisConfig.defaultWd],
    //     projection, //数据的投影坐标系
    //     zoom: shandongPgisConfig.defaultZoom,
    //     minZoom: shandongPgisConfig.minZoom,
    //     maxZoom: shandongPgisConfig.maxZoom,
    //   });
    //   // 创建地图
    //   this.mapInstance = new Map({
    //     layers: [layer],
    //     view: this.mapView,
    //     target: 'olMap',
    //   });
    // },
    // 山东省厅天地图
    sdTianMapInit() {
      //   let projection = olProj.get(TileConfig.projection);
      //   let tileGrid = new Tilegrid.WMTS({
      //     //TileGrid WMTS
      //     origin: TileConfig.tileGrid.origin, // 设置原点坐标 TileConfig.tileGrid.origin ol.extent.getTopLeft(projectionExtent)
      //     resolutions: TileConfig.tileGrid.resolutions, // 设置分辨率
      //     matrixIds: TileConfig.tileGrid.matrixIds,
      //     // extent:[ 114.229839088925,33.9389305555556 ,123.400530149205 ,38.9048194444444], //112.52197,34.05761,123.53027,39.39697    -180,-90,180,90  114.229839088925 33.9389305555556 123.400530149205 38.9048194444444
      //     tileSize: [256, 256],
      //   });
      //   let layer = new layerTile({
      //     opacity: 0.7,
      //     source: new WMTS({
      //       url: 'http://10.48.142.163/tileservice/sdmap2000?',
      //       layer: 'vector',
      //       style: 'default',
      //       matrixSet: 'SDMap2000', //投影坐标系设置矩阵
      //       format: 'image/png', //  图片格式
      //       wrapX: true,
      //       version: '1.0.0',
      //       tileGrid: tileGrid,
      //     }),
      //   });
      //   this.mapView = new View({
      //     center:window.g.center,
      //     projection, //数据的投影坐标系
      //     zoom: window.g.defaultZoom,
      //     minZoom: window.g.minZoom,
      //     maxZoom: window.g.maxZoom,
      //   });
      //   // 创建地图
      //   this.mapInstance = new Map({
      //     layers: [layer],
      //     view: this.mapView,
      //     target: 'olMap',
      //   });
    },
    // 北京海淀百度地图
    // haidianMapInit() {
    //   let projection = olProj.get(haidianBaiduMapConfig.projection);
    //   var layer = new layerTile({
    //     source: new XYZ({
    //       url: 'http://14.120.5.222:8219/tile?x={x}&y={y}&z={z}',
    //     }),
    //   });

    //   //实例化比例尺控件
    //   var scaleLineControl = new ScaleLine({
    //     //设置度量单位为米
    //     units: 'metric',
    //     target: 'ol-scale-line',
    //     className: 'ol-scale-line',
    //   })();

    //   this.mapView = new View({
    //     center: [haidianBaiduMapConfig.defaultJd, haidianBaiduMapConfig.defaultWd],
    //     projection,
    //     zoom: haidianBaiduMapConfig.defaultZoom,
    //     minZoom: haidianBaiduMapConfig.minZoom,
    //     maxZoom: haidianBaiduMapConfig.maxZoom,
    //   });
    //   // 创建地图
    //   this.mapInstance = new Map({
    //     layers: [layer],
    //     view: this.mapView,
    //     target: 'olMap',
    //     controls: Control.defaults({
    //       zoom: false,
    //       rotate: false,
    //       attribution: false,
    //     }),
    //   });
    //   this.mapInstance.addControl(scaleLineControl);
    // },
    // 高德外网地图初始化
    gaoDeInternetInitMap() {
      const layer = createLayer('Amap');
      this.mapView = new View({
        center: window.g.center,
        projection: 'EPSG:4326',
        zoom: window.g.defaultZoom,
        minZoom: window.g.minZoom,
        maxZoom: window.g.maxZoom,
      });
      // 创建地图
      this.mapInstance = new Map({
        layers: [].concat(layer),
        view: this.mapView,
        target: 'olMap',
        controls: Control.defaults({
          zoom: false,
          rotate: false,
          attribution: false,
        }),
      });
    },
    // 上海高德内网地图初始化
    gaoLANDeInitMap() {
      //图层
      let layerGroup = new LayerGroup({
        layers: [
          new layerTile({
            preload: 4,
            source: new XYZ({
              projection: 'EPSG:3857',
              url: 'http://15.75.0.255:25003/v3/tile?x={x}&y={y}&z={z}',
            }),
          }),
          new layerTile({
            preload: 4,
            source: new XYZ({
              projection: 'EPSG:3857',
              url: 'http://15.75.0.255:25033/v3/tile?x={x}&y={y}&z={z}',
            }),
          }),
          new layerTile({
            preload: 4,
            source: new XYZ({
              projection: 'EPSG:3857',
              url: 'http://15.75.0.255:25777/v3/tile?x={x}&y={y}&z={z}',
            }),
          }),
        ],
      });

      this.mapView = new View({
        center: window.g.center,
        projection: 'EPSG:4326',
        zoom: window.g.defaultZoom,
        minZoom: window.g.minZoom,
        maxZoom: window.g.maxZoom,
      });

      //实例化比例尺控件
      var scaleLineControl = new ScaleLine({
        //设置度量单位为米
        units: 'metric',
        target: 'ol-scale-line',
        className: 'ol-scale-line',
      })();

      // 创建地图
      this.mapInstance = new Map({
        layers: layerGroup,
        view: this.mapView,
        target: 'olMap',
        controls: Control.defaults({
          zoom: false,
          rotate: false,
          attribution: false,
        }),
      });
      this.mapInstance.addControl(scaleLineControl);
    },
    // 苏州吴江顺丰内网地图初始化
    wjSfInitMap() {
      let layerGroup = new LayerGroup({
        layers: [
          new layerTile({
            source: new XYZ({
              crossOrigin: 'anonymous',
              wrapX: false,
              projection: 'EPSG:4326',
              url:
                'http://50.79.80.195:8090/MapTileService/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&STYLE=default&STORETYPE=merged-dat&LAYER=wmts_4326_320500&PROJECTION=4326&TILEMATRIXSET=c&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image/png',
            }),
          }),
        ],
      });

      this.mapView = new View({
        center: window.g.center,
        projection: 'EPSG:4326',
        zoom: window.g.defaultZoom,
      });

      //实例化比例尺控件
      // var scaleLineControl = new ScaleLine({
      //   //设置度量单位为米
      //   units: 'metric',
      //   target: 'ol-scale-line',
      //   className: 'ol-scale-line',
      // })();

      // 创建地图
      this.mapInstance = new Map({
        layers: layerGroup,
        view: this.mapView,
        target: 'olMap',
        // controls: Control.defaults({
        //   zoom: false,
        //   rotate: false,
        //   attribution: false,
        // }),
      });
      // this.mapInstance.addControl(scaleLineControl);
    },
    // 贵阳南明区北大方正地图
    NanMingMapInit() {
      const layers = NanMingMapConfig.map.basemapLayers[0].layers[0];
      const view = NanMingMapConfig.map.view;
      const layer = createLayer({
        type: layers.source.type,
        ...layers.source.options,
      });
      this.mapView = new View({ ...view });
      this.mapInstance = new Map({
        layers: [].concat(layer),
        view: this.mapView,
        target: 'olMap',
      });
    },
    // 安徽省厅超图SuperMap
    ahSuperMapInit() {
      //   this.mapView = ahView;
      //   this.mapInstance = new Map({
      //     layers: [ahLayer],
      //     view: ahView,
      //     target: 'olMap',
      //   });
    },
    // 获取地图缩放等级
    getZoom() {
      return this.mapView.getZoom();
    },
    // 获取地图缩放等级
    getMaxZoom() {
      return this.mapView.get('maxZoom');
    },
    /**
     * 地图是否可以缩放
     * @param {Boolean} active false：当前地图不可缩放。true：可缩放
     */
    mouseWheelZoom(active = true) {
      try {
        let getMouseWheelZoom = () => {
          let pan;
          this.mapInstance.getInteractions().forEach(e => {
            if (e instanceof olInteraction.MouseWheelZoom) pan = e;
          });
          return pan;
        };
        let MouseWheelZoom = getMouseWheelZoom();
        MouseWheelZoom.setActive(active);
      } catch (err) {
        console.log('mouseWheelZoom=', err);
      }
    },
    /**
     * 设置地图缩放等级
     * @param {Number} zoom 缩放等级 默认最大等级
     */
    setZoom(zoom = window.g.minZoom) {
      this.mapView.setZoom(zoom);
    },
    setCenter(center = window.g.center) {
      this.mapView.setCenter(center);
    },
    // 清除地图相关数据包括数据覆盖物图层
    clearMapObject() {
      this.clearHeatMap(); // 清除热力图
      this.clearPoi(); // 清除poi
      this.clearMarker(); // 清除 marker
      this.clearClusters(); // 清除类聚
      this.removeOverlays(); // 清除辖区分布
      this.removePoiOverlays(); // 清除poi 覆盖物
    },
    /**
     * 创建区域边界
     * @param {Array} data 父组件传参【边界数组】
     */
    createAreaBorder(data) {
      data.forEach((item, index) => {
        let coordinates = toCoordinate(item.area);
        let vectorLayerBorder = new layerVector({
          style: new Style({
            stroke: new Stroke({
              color: '#258ad7',
              width: 2,
            }),
          }),
          zIndex: 1,
        });
        //区域边界图层
        var polygon = new geomPolygon([coordinates]);
        var feature = new Feature({
          geometry: polygon,
          id: index,
          type: 'polygon',
        });
        var vectorSource = new SourceVector();
        vectorSource.addFeature(feature);
        vectorLayerBorder.setSource(vectorSource);
        this.mapInstance.addLayer(vectorLayerBorder);
        this.vectorLayerBorders.push(vectorLayerBorder);
      });
    },
    /**
     * 创建区域覆盖物
     * @param {Object} item 创建当前辖区派出所的对象
     * @param {Number} index 创建当前辖区派出所的索引
     *
     */
    createKeyAreas(item, index) {
      let el = this.$refs.keyAreasOverlayDom[index];
      let KeyAreasOverlay = new Overlay({
        element: el,
        //   positioning: "top-left", //设置以后屏幕抖动
        offset: [-50, -50],
        position: [item[this.props.longitude], item[this.props.latitude]],
        stopEvent: false,
      });
      this.mapInstance.addOverlay(KeyAreasOverlay);
      this.keyAreasOverlays.push(KeyAreasOverlay);

      // overlays.push(KeyAreasOverlay);
    },
    /**
     * 移除区域边界
     */
    removeVectorLayerBorder() {
      this.vectorLayerBorders.forEach(item => {
        this.mapInstance.removeOverlay(item);
      });
      this.vectorLayerBorders = [];
    },
    //移除区域覆盖物
    removeOverlays() {
      this.keyAreasOverlays.forEach(item => {
        this.mapInstance.removeOverlay(item);
      });
      this.keyAreasOverlays = [];
    },
    //初始化辖区分布
    initKeyArea() {
      this.dataList.value.forEach((item, index) => {
        this.createKeyAreas(item, index);
      });
    },
    // 创建标点
    createPoi(item, index) {
      let el = this.$refs.overlay[index];
      let poiOverlay = new Overlay({
        element: el,
        //   positioning: "top-left", //设置以后地图卡顿
        offset: [0, 0],
        positioning: 'center-center',
        position: [item[this.props.longitude], item[this.props.latitude]],
        stopEvent: false,
      });
      this.mapInstance.addOverlay(poiOverlay);
      this.poiOverlays.push(poiOverlay);
    },
    /**
     * 地图覆盖物辖区分析Mouseenter事件
     * @param {Object} item 覆盖物信息对象
     * @param {Number} index 覆盖索引
     *
     */
    keyAreasOverlayMouseenter(item, index) {
      if (!item.area) return false;
      this.vectorLayerBorders.forEach(item => {
        item.setStyle(
          new Style({
            stroke: new Stroke({
              color: '#258ad7',
              width: 2,
            }),
            zIndex: 1,
          }),
        );
      });
      this.vectorLayerBorders[index].setStyle(
        new Style({
          fill: new Fill({
            color: 'rgba(37,138,215, 0.2)',
          }),
          stroke: new Stroke({
            color: '#258ad7',
            width: 2,
          }),
          zIndex: 99,
        }),
      );
    },
    /**
     * 地图覆盖物辖区分析Mouseleave事件
     * @param {Object} item 覆盖物信息对象
     * @param {Number} index 覆盖索引
     *
     */
    keyAreasOverlayMouseleave(item) {
      //   console.log("地图覆盖物辖区分析Mouseleave事件", index);
      if (!item.area) return false;
      this.vectorLayerBorders.forEach(item => {
        item.setStyle(
          new Style({
            stroke: new Stroke({
              color: '#258ad7',
              width: 2,
            }),
            zIndex: 1,
          }),
        );
      });
      //   this.vectorLayerBorders[index].setStyle(
      //     new Style({
      //       stroke: new Stroke({
      //         // lineDash:[1,2,3,4,5,6],
      //         color: "#258ad7",
      //         // color: '#ffcc33',
      //         width: 2
      //       }),
      //       zIndex: 1
      //     })
      //   );
      // this.mapInstance.removeLayer(this.vectorLayerBorder);
    },
    /**
     * 创建poi图层
     */
    createPoiLayer() {
      this.poiLayer = new layerVector({
        source: new SourceVector(),
        zIndex: 2,
      });
    },

    /**
     * 初始化poi
     */
    initPoi() {
      // 创建poi图层
      this.createPoiLayer();
      this.dataList.value.forEach((item, index) => {
        this.createPoi(item, index);
      });
      this.mapInstance.addLayer(this.poiLayer);
    },
    //移除poi覆盖物
    removePoiOverlays() {
      this.poiOverlays.forEach(item => {
        this.mapInstance.removeOverlay(item);
      });
      this.poiOverlays = [];
    },
    /**
     * 初始化热力图
     */
    quyerHeatMapData() {},
    clearMarker() {
      // console.log('clearMarker')
      // markerVectorLayer && this.markerVectorLayer.getSource().clear();
      sourceVector && sourceVector.clear();
      markerVectorLayer && this.mapInstance.removeLayer(markerVectorLayer);

      markerFeatures = [];
      sourceVector = null;
      markerVectorLayer = null;
    },
    // 清除标点
    clearPoi() {
      this.poiLayer && this.poiLayer.getSource().clear();
    },
    // 清除热力图
    clearHeatMap() {
      this.mapInstance.getLayers().forEach(function (layer) {
        if (layer instanceof Heatmap) {
          layer.getSource().clear(true);
        }
      });
    },
    /**
     * @description: 创建marker
     * @param {*}
     * @return {*}
     */
    createMarker() {
      console.log('createMarker start');
      // 要素
      this.dataList.value.forEach((item, index) => {
        let type = 'marker'; // marker 类型
        let coordinates = [Number(item[this.props.longitude]), Number(item[this.props.latitude])];
        let geometry = new geomPoint(coordinates);

        markerFeatures.push(
          new Feature({
            geometry,
            item,
            id: index,
            type,
          }),
        );
      });

      let getMarkerStyle = () => {
        let svg =
          '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">' +
          '<path fill="#156BB1" d="M22.906,10.438c0,4.367-6.281,14.312-7.906,17.031c-1.719-2.75-7.906-12.665-7.906-17.031S10.634,2.531,15,2.531S22.906,6.071,22.906,10.438z"/>' +
          '<circle fill="#FFFFFF" cx="15" cy="10.677" r="3.291"/></svg>';
        let mysvg = new Image();
        mysvg.src = 'data:image/svg+xml,' + escape(svg);
        let image = new Icon({
          img: mysvg, // 设置Image对象
          imgSize: [30, 30], // 及图标大小
        });

        let style = new Style({
          image: image,
        });
        return style;
      };
      let getClusterStyle = text => {
        text = text + '';
        let image = new Circle({
          radius: 18,
          fill: new Fill({
            color: '#2d8cf0',
          }),
        });
        let style = new Style({
          image,
          text: new Text({
            text,
            fill: new Fill({
              color: '#fff',
            }),
            scale: 0.8,
          }),
        });
        return style;
      };

      // 图层添加到地图实例
      if (markerVectorLayer) {
        sourceVector.addFeatures(markerFeatures);
        markerVectorLayer.setSource(sourceVector);
      } else {
        //矢量要素数据源
        sourceVector = new SourceVector({
          features: markerFeatures,
        });
        // 图层
        markerVectorLayer = new layerVector({
          source: sourceVector,
          style: function (feature) {
            let item = feature.get('item');
            let style =
              item.heapNum && item.heapNum > 1 ? getClusterStyle(item.heapNum) : getMarkerStyle();

            return style;
          },
        });
        this.mapInstance.addLayer(markerVectorLayer);
      }
    },
    //聚类
    createCluster(features) {
      //矢量要素数据源
      var source = new SourceVector({
        features: features,
      });
      //聚合标注数据源
      this.clusterSource = new Cluster({
        distance: 40,
        source: source,
      });

      let getCircleStyle = features => {
        let nums = features.map(f => f.get('item').num);
        let total = nums.reduce((a, b) => a + b); // 计算当前聚合点的警情数
        let url = window.g.PngUrl + window.g.staticUrl + '/static/openlayers/image/circleBlue.png';
        let image = new Icon({
          src: url,
        });
        return [
          new Style({
            image: image,
            text: new Text({
              text: total.toString(),
              fill: new Fill({
                color: '#fff',
              }),
            }),
          }),
        ];
      };

      let getMarkerStyle = features => {
        let svg =
          '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">' +
          '<path fill="#156BB1" d="M22.906,10.438c0,4.367-6.281,14.312-7.906,17.031c-1.719-2.75-7.906-12.665-7.906-17.031S10.634,2.531,15,2.531S22.906,6.071,22.906,10.438z"/>' +
          '<circle fill="#FFFFFF" cx="15" cy="10.677" r="3.291"/></svg>';
        let mysvg = new Image();
        mysvg.src = 'data:image/svg+xml,' + escape(svg);
        let image = new Icon({
          img: mysvg, // 设置Image对象
          imgSize: [30, 30], // 及图标大小
        });
        let style = [];
        features.forEach(() => {
          style.push(
            new Style({
              image: image,
            }),
          );
        });
        return style;
      };

      let getRepeatMarkerStyle = features => {
        let total = features[0].get('item').num;
        let image = new Circle({
          radius: 18,
          stroke: new Stroke({
            color: '#fff',
          }),
          fill: new Fill({
            color: '#FF9812',
          }),
        });
        return [
          new Style({
            image: image,
            text: new Text({
              text: total.toString(),
              fill: new Fill({
                color: '#fff',
              }),
            }),
          }),
        ];
      };
      let maxZoom = this.mapInstance.getView().get('maxZoom');
      this.clustersLayer = new layerVector({
        source: this.clusterSource,
        zIndex: 2,
        style: feature => {
          let zoom = this.mapInstance.getView().getZoom();
          let features = feature.get('features');
          let featuresSize = features.length;
          // console.log('featuresSize=',featuresSize)
          let style = [];
          let isAllRepeat = features.every(f => f.get('type') === 'repeat'); // 当前要素中是否存在在多条警情在同一个经纬度
          if (!isAllRepeat && featuresSize == 1) {
            style = getMarkerStyle(features);
          } else if (featuresSize > 1 && maxZoom !== zoom) {
            style = getCircleStyle(features);
          } else if (isAllRepeat && featuresSize === 1) {
            style = getRepeatMarkerStyle(features);
          } else if (featuresSize > 1 && maxZoom === zoom) {
            // 最大缩放层级时默认展开全部聚合点
            style = getMarkerStyle(features);
          }
          return style;
        },
      });
    },

    // 清除聚类
    clearClusters() {
      if (this.clusterSource) {
        this.clusterSource.clear();
        this.clustersLayer.getSource().clear();
        this.mapInstance.removeLayer(this.clustersLayer);
      }
    },
    //初始化聚类
    initCluster() {
      if (this.dataList.value.length === 0) {
        return;
      }
      let features = [];
      this.dataList.value.forEach((item, index) => {
        var coordinates = [Number(item[this.props.longitude]), Number(item[this.props.latitude])];
        features[index] = new Feature({
          geometry: new geomPoint(coordinates),
          item: item,
          id: index,
          type: item.num > 1 ? 'repeat' : 'point',
          cluster: true,
        });
      });

      this.createCluster(features);
      this.mapInstance.addLayer(this.clustersLayer);
      let center = [];
      if (this.dataList.value.every(o => toString.call(o) === '[object Number]')) {
        center[0] = arrAverageNum(this.dataList.value.map(item => item[this.props.longitude]));
        center[1] = arrAverageNum(this.dataList.value.map(item => item[this.props.latitude]));
        this.setCenter(center);
      }
    },
    /**
     * @description: 移除事件
     * @param {*} event
     * @return {*}
     */
    removeEvent(event) {
      new Observable.unByKey(event);
    },
    /**
     * 为地图|覆盖物添加事件
     */
    addMouseEvent() {
      this.moveendEventHandle = this.mapInstance.on('moveend', e => {
        this.$emit('moveend', e);
      });
      this.movestartEventHandle = this.mapInstance.on('movestart', e => {
        this.$emit('movestart', e);
      });
    },
  },
});
</script>

<style>
.ol-map {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.ol-map .ol-scale-line {
  right: 8px;
  left: unset;
  z-index: 9;
  z-index: 9;
  background: rgba(0, 60, 136, 0.7);
}

.ol-scale-line-inner {
  /* 比例尺边框样式 */
  color: #eee;
  font-size: 10px;
  border: 1px solid #eee;
  border-top: none;
}

/* 打点 */
.overlay-marker {
  width: 20px;
  height: 28px;
  color: #fff;
  font-size: 12px;
  line-height: 28px;
  text-align: center;
  /* background-image: url(../../../static/openlayers/image/icon_location_blue.png); */
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 20px 28px;
  cursor: pointer;
}
.overlay-marker:hover {
  /* background-image: url(../../../static/openlayers/image/icon_location_orange.png); */
  background-size: 20px 28px;
}
.overlay-marker.active {
  /* background-image: url(../../../static/openlayers/image/icon_location_orange.png); */
  background-size: 20px 28px;
}
/* 圆形聚合样式 */
.circular-cluster-style {
  width: 58px;
  height: 58px;
  overflow: hidden;
  color: #fff;
  font-size: 12px;
  text-align: center;
  background: #258ad7;
  border-radius: 50%;
  cursor: pointer;
}

.circle-container {
  display: inline-block;
  box-sizing: content-box;
  min-width: 50px;
  min-height: 50px;
  padding: 5px;
  color: #fff;
  font-size: 12px;
  line-height: 1;
  white-space: nowrap;
  text-align: center;
  background: #258ad7;
  border-radius: 50%;
  cursor: pointer;
  -moz-user-select: none; /* 火狐 */
  -webkit-user-select: none; /* 谷歌 */
  -ms-user-select: none; /* IE */
  user-select: none;
}
.circle-container:before {
  display: inline-block;
  height: 0;
  padding-top: 100%;
  vertical-align: middle;
  content: '';
}
.circle-container > div {
  display: inline-block;
  vertical-align: middle;
}

.security-area span {
  display: block;
}
.security-area .area {
  padding-top: 11px;
}
.security-area .num {
  padding-top: 1px;
}
.ol-overlay-container:hover {
  z-index: 10;
}
/* 乱点 */
.security {
  height: 32px;
  padding: 0 15;
  padding: 0 15px;
  color: #fff;
  font-size: 14px;
  line-height: 32px;
  text-align: left;
  background: #258ad7;
  border-radius: 0;
  border-radius: 0;
  cursor: pointer;
}
.security::after {
  position: absolute;
  top: 100%;
  left: 50%;
  border-top: solid 7px #258ad7;
  border-right: solid 7px #00800000;
  border-bottom: solid 0px #00800000;
  border-left: solid 7px #00800000;
  content: '';
}
.security:hover {
  background: #eb7207;
}
.security:hover::after {
  border-top: solid 7px #eb7207;
}

.security .address {
  float: left;
  max-width: 250px;
  padding-right: 15px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
